/**
 * 基础服务类
 * 提供通用的CRUD操作和查询方法
 */

class BaseService {
  constructor(model) {
    this.model = model;
  }

  /**
   * 创建记录
   * @param {Object} data 创建数据
   * @returns {Promise<Object>} 创建的记录
   */
  async create(data) {
    try {
      const record = new this.model(data);
      return await record.save();
    } catch (error) {
      throw new Error(`创建失败: ${error.message}`);
    }
  }

  /**
   * 根据ID查找记录
   * @param {string} id 记录ID
   * @param {string} populate 关联字段
   * @returns {Promise<Object|null>} 查找到的记录
   */
  async findById(id, populate = '') {
    try {
      let query = this.model.findById(id);
      if (populate) {
        query = query.populate(populate);
      }
      return await query;
    } catch (error) {
      throw new Error(`查找失败: ${error.message}`);
    }
  }

  /**
   * 分页查询
   * @param {Object} options 查询选项
   * @returns {Promise<Object>} 分页结果
   */
  async findWithPagination(options = {}) {
    try {
      const {
        query = {},
        page = 1,
        limit = 10,
        sort = '-createdAt',
        populate = '',
        select = ''
      } = options;

      const pageNumber = parseInt(page);
      const limitNumber = parseInt(limit);
      const skip = (pageNumber - 1) * limitNumber;

      // 构建查询
      let mongoQuery = this.model.find(query);
      
      if (populate) {
        mongoQuery = mongoQuery.populate(populate);
      }
      
      if (select) {
        mongoQuery = mongoQuery.select(select);
      }

      // 执行查询
      const [data, total] = await Promise.all([
        mongoQuery.sort(sort).skip(skip).limit(limitNumber),
        this.model.countDocuments(query)
      ]);

      return {
        data,
        pagination: {
          page: pageNumber,
          limit: limitNumber,
          total,
          pages: Math.ceil(total / limitNumber),
          hasNext: pageNumber < Math.ceil(total / limitNumber),
          hasPrev: pageNumber > 1
        }
      };
    } catch (error) {
      throw new Error(`分页查询失败: ${error.message}`);
    }
  }

  /**
   * 更新记录
   * @param {string} id 记录ID
   * @param {Object} data 更新数据
   * @returns {Promise<Object|null>} 更新后的记录
   */
  async updateById(id, data) {
    try {
      return await this.model.findByIdAndUpdate(
        id,
        { ...data, updatedAt: new Date() },
        { new: true, runValidators: true }
      );
    } catch (error) {
      throw new Error(`更新失败: ${error.message}`);
    }
  }

  /**
   * 删除记录
   * @param {string} id 记录ID
   * @returns {Promise<Object|null>} 删除的记录
   */
  async deleteById(id) {
    try {
      return await this.model.findByIdAndDelete(id);
    } catch (error) {
      throw new Error(`删除失败: ${error.message}`);
    }
  }

  /**
   * 批量删除
   * @param {Array} ids ID数组
   * @returns {Promise<Object>} 删除结果
   */
  async deleteMany(ids) {
    try {
      return await this.model.deleteMany({ _id: { $in: ids } });
    } catch (error) {
      throw new Error(`批量删除失败: ${error.message}`);
    }
  }

  /**
   * 搜索记录
   * @param {Object} options 搜索选项
   * @returns {Promise<Array>} 搜索结果
   */
  async search(options = {}) {
    try {
      const {
        keyword,
        fields = ['name'],
        limit = 10,
        populate = ''
      } = options;

      if (!keyword) {
        return [];
      }

      // 构建搜索条件
      const searchConditions = fields.map(field => ({
        [field]: { $regex: keyword, $options: 'i' }
      }));

      let query = this.model.find({ $or: searchConditions });
      
      if (populate) {
        query = query.populate(populate);
      }

      return await query.limit(parseInt(limit));
    } catch (error) {
      throw new Error(`搜索失败: ${error.message}`);
    }
  }

  /**
   * 统计记录数量
   * @param {Object} query 查询条件
   * @returns {Promise<number>} 记录数量
   */
  async count(query = {}) {
    try {
      return await this.model.countDocuments(query);
    } catch (error) {
      throw new Error(`统计失败: ${error.message}`);
    }
  }

  /**
   * 检查记录是否存在
   * @param {Object} query 查询条件
   * @returns {Promise<boolean>} 是否存在
   */
  async exists(query) {
    try {
      const count = await this.model.countDocuments(query);
      return count > 0;
    } catch (error) {
      throw new Error(`检查存在性失败: ${error.message}`);
    }
  }

  /**
   * 聚合查询
   * @param {Array} pipeline 聚合管道
   * @returns {Promise<Array>} 聚合结果
   */
  async aggregate(pipeline) {
    try {
      return await this.model.aggregate(pipeline);
    } catch (error) {
      throw new Error(`聚合查询失败: ${error.message}`);
    }
  }
}

module.exports = BaseService;
